#include <string.h>
#include <windows.h>

#include "lib.h"
#include "patch.h"
#include "admupd.h"
#include "admpipe.h"

#include "patchsrv.h"
#include "pkglist.h"
#include "pkgdesc.h"

//
// This protocol assumes the client on the other end of the pipe has rejected
// all invalid update attempts (i.e. dups and non-existent files aren't
// checked here).
//
void
AdminUpdatePkg::handle(uint8* msg, int32 len)
{
	if (pipe->isLoggedOn())
	{
		uint8 *name, *zip;
		int32 index;
		uint32 version;
		uint8* pver;
		PackageDescription* pkg;
		PackageList* list;

		index = (int32)msg[1];	// skip <U>

		name = msg + 3;			// skip <U><index><name len>

		pver = name + msg[2];	// point to version
		version = (uint32)(
			(pver[3] & 0xFF) |
			((pver[2]<<8)&0xFF00) |
			((pver[1]<<16)&0xFF0000) |
			((pver[0]<<24)&0xFF000000));

		name[name[-1]] = '\0';

		zip = pver + 4 + 1;
		zip[zip[-1]] = '\0';		// ASSUMES 1 byte avail after msg!
		
		list = PatchServer::This->lockPackageList();
		if (!list)
		{
			PatchServer::This->unlockPackageList();
			pipe->sendError(APE_MEMORY_ERROR);
			return;
		}

		pkg = list->getItem(index);
		if (!pkg)
		{
			PatchServer::This->unlockPackageList();
			pipe->sendError(APE_UNKNOWN_PACKAGE);
			return;
		}

//		if (0 != strcmpi((char*)name, pkg->getName()))
		if (pkg->getName() == (char*)name)
		{
			PatchServer::This->unlockPackageList();
			pipe->sendError(APE_INVALID_UPDATE);
			return;
		}

		if (pkg->set((char*)name, version, (char*)zip))
		{
			list->save(true);

			pipe->msgStart();
			pipe->msgAdd('S');
			pipe->msgEnd();
		}
		else
			pipe->sendError(APE_MEMORY_ERROR);

		PatchServer::This->unlockPackageList();
	}
	else
		pipe->sendError(APE_UNKNOWN_REQUEST);
}
